#ifndef __CORE_COMMON_PLATFORM_H_INCLUDE__
#define __CORE_COMMON_PLATFORM_H_INCLUDE__

// C headers used by common
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <stdarg.h>
#include <math.h>

// C++ headers used by common
#include <string>
#include <list>
#include <vector>
#include <map>
#include <set>
#include <algorithm>

typedef bool            bool8;
typedef signed char		int8;
typedef unsigned char	uint8;
typedef signed short	int16;
typedef unsigned short	uint16;
typedef signed int		int32;
typedef unsigned int	uint32;

#if defined(WIN32) || defined(WIN64)

#define OS_PLATFORM_WINDOWS

#ifndef WINVER
	#define WINVER 0x0501
#endif

#ifndef _WIN32_WINNT
	#define _WIN32_WINNT 0x0501
#endif 

#ifndef _WIN32_WINDOWS
	#define _WIN32_WINDOWS 0x0410
#endif

#ifndef _WIN32_IE
	#define _WIN32_IE 0x0600
#endif

#ifndef WIN32_LEAN_AND_MEAN
	#define WIN32_LEAN_AND_MEAN
#endif //WIN32_LEAN_AND_MEAN

#ifndef EXCLUDE_WINDOW_H
	#include <windows.h>
#endif //EXCLUDE_WINDOW_H

#include <winsock2.h>
#include <ws2tcpip.h>
#include <process.h>
#include <shlwapi.h>
#include <io.h>

#if defined(WIN32)
	#define ARCH_I386
	typedef __int64 int64;
	typedef unsigned __int64 uint64;
	#define _I64FMT_ "%I64d"
	#define _U64FMT_ "%I64u"
	#define _X64FMT_ "%I64X"
	#define _SIZE_TFMT_ "%lu"
#elif defined(WIN64)
	#define ARCH_x86_64
	typedef __int64 int64;
	typedef unsigned __int64 uint64;
	#define _I64FMT_ "%I64d"
	#define _U64FMT_ "%I64u"
	#define _X64FMT_ "%I64X"
	#define _SIZE_TFMT_ "%lu"
#endif //I386

#define MSG_NOSIGNAL 0
#define SIGHUP       1
#define SIGQUIT      3
#define SIGKILL      9

#define snprintf _snprintf
#define fseek64  _fseeki64
#define ftell64  _ftelli64
#define WEXITSTATUS(n) n

#ifdef _Printf_format_string_
#define __FMT_PRINT_PARAM__ _Printf_format_string_
#endif //_Printf_format_string_
#define __FMTCHECK__(func,m,n)

#ifndef __STDCALL
	#define __STDCALL __stdcall
#endif //__STDCALL

#ifndef __CDECL
	#define __CDECL   __cdecl
#endif //__CDECL

#if defined(CORE_CORE_COMMON_STATIC____) || defined(CORE_COMMON_INLINE__)
	#define CORE_COMMON_API__
	#define CORE_COMMON_TPL__
#elif defined(CORE_COMMON_EXPORT__)
	#define CORE_COMMON_API__ __declspec(dllexport)
	#define CORE_COMMON_TPL__
#elif defined(CORE_COMMON_IMPORT__)
	#define CORE_COMMON_API__ __declspec(dllimport)
	#define CORE_COMMON_TPL__ extern
#else
	#define CORE_COMMON_API__
	#define CORE_COMMON_TPL__
#endif

#elif defined(LINUX32) || defined(LINUX64)

#define OS_PLATFORM_LINUX

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <net/if.h>
#ifndef ANDROID
#include <net/ethernet.h>
#else
#include <net/ethertypes.h>
#include <linux/if_ether.h>
#include <sys/wait.h>
#include <ctype.h>
#endif
#include <netinet/in.h>
#include <netinet/ether.h>
#include <netpacket/packet.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <fcntl.h>
#include <dirent.h>
#include <netdb.h>

#if !defined(LINUX64) && (_FILE_OFFSET_BITS != 64)
	#error "Linux off_t is not 64-bit, should define _FILE_OFFSET_BITS=64"
#endif //sizeof(off_t) != 8

#if defined(LINUX32)
	#define ARCH_I386
	typedef long long int64;
	typedef unsigned long long uint64;
	#define _I64FMT_ "%lld"
	#define _U64FMT_ "%llu"
	#define _X64FMT_ "%llX"
	#define _SIZE_TFMT_ "%u"
#elif defined(LINUX64)
	#define ARCH_x86_64
	typedef long int64;
	typedef unsigned long uint64;
	#define _I64FMT_ "%ld"
	#define _U64FMT_ "%lu"
	#define _X64FMT_ "%lX"
	#define _SIZE_TFMT_ "%lu"
#endif //I386

typedef void *HANDLE;
#define __FMT_PRINT_PARAM__
#define __FMTCHECK__(func,m,n) __attribute__((format(func,m,n)))

#define ERROR_SUCCESS            0
#define ERROR_ALREADY_EXISTS     EEXIST
#define ERROR_NOT_READY          ENOENT
#define ERROR_ACCESS_DENIED      EPERM
#define ERROR_NO_DATA            ENOENT
#define ERROR_TIMEOUT            ETIMEDOUT
#define ERROR_CONNECTION_REFUSED ECONNREFUSED
#define ERROR_INVALID_PARAMETER  ERANGE
#define ERROR_NOT_SUPPORTED      ENODATA
#define ERROR_INTERNAL_ERROR     EFAULT
#define ERROR_IO_DEVICE          EIO

#define closesocket close
#define ioctlsocket ioctl
#define fseek64     fseeko
#define ftell64     ftello

#define __STDCALL
#define __CDECL
#define CORE_COMMON_API__
#define CORE_COMMON_TPL__

#else
#error WIN32|WIN64 or LINUX32|LINUX64 os platform should be defined.
#endif //

#define VALIDATE_ERROR_RETURN(expr, ecode, ret) \
	if( expr )\
{\
	core::common::setErrorCode(ecode); \
	return ret; \
}

#define DISALLOW_COPY_AND_ASSIGN(cls) private:\
	cls( const cls & );\
	cls & operator =( const cls & )

// debug
//#include <core/common/debug-new.h>

#endif //__CORE_COMMON_PLATFORM_H_INCLUDE__

